#region Copyright and Licensing Notice
// Copyright (C) 2011 Steven Bosnick
// 
// This program is open source software; you can redistribute it 
// and/or modifiy it under the terms of the Eclipse Public License,
// version 1.0.
// 
// This program is distributed in the hope that it will be useful, 
// but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A 
// PARTICULAR PURPOSE. See the Eclipse Public License for more
// details.
// 
// You should have received a copy of the Eclipse Public License 
// along with this program; if not, you can find a copy at
// "http://www.opensource.org/licenses/eclipse-1.0.php".
#endregion
using System;
using System.Threading.Tasks;
using BitwiseOre.SharedMemory;
using BitwiseOre.SharedMemory.Core;
using BitwiseOre.SharedMemory.Utils;
using Moq;
using NUnit.Framework;

namespace BitwiseOre.Tests.SharedMemory
{
    [TestFixture]
    public sealed class SharedMemoryFactoryFixture : AssertionHelper
    {
        [Test(Description = "Checks that disposing of the factory delgates to the disposer.")]
        public void Dispose_DelegatesToDisposer()
        {
            var disposer = new Mock<IDisposer<SharedMemoryFactory>>();
            var factory = new SharedMemoryFactory(disposer.Object, new Mock<IConnector>().Object, null, null);

            factory.Dispose();

            disposer.Verify(d => d.Dispose(), "Dispose did not delegate to the dispoer.");
        }

        [Test(Description = "Checks that beginning a connect operation delegates to the connection factory.")]
        public void BeginConnect_DelegateToInternalFactory()
        {
            var connfactory = new Mock<IConnector>();
            connfactory.Setup(cf => cf.Connect(It.IsAny<TimeSpan>(), It.IsAny<Func<Guid, SharedMemoryStream>>()))
                .Returns(new Task<SharedMemoryStream>(() => null));
            Func<Guid, SharedMemoryStream> streamfactory = g => null;
            var factory = new SharedMemoryFactory(new Mock<IDisposer<SharedMemoryFactory>>().Object,
                                                  connfactory.Object, streamfactory, null);

            factory.BeginConnect(null, null);

            connfactory.Verify(cf => cf.Connect(It.IsAny<TimeSpan>(),
                                                It.Is<Func<Guid, SharedMemoryStream>>(f => f == streamfactory)),
                               "Connection factory not called or called with unexpected parameters.");
        }

        [Test(Description = "Checks that ending a connect operation delegates to the task ender")]
        public void EndConnect_DelegatesToTaskEnder()
        {
            var ender = new Mock<IAsyncResultEnder<SharedMemoryStream>>();
            var factory = new SharedMemoryFactory(new Mock<IDisposer<SharedMemoryFactory>>().Object,
                                                  new Mock<IConnector>().Object, g => null,
                                                  ender.Object);
            var task = Task<SharedMemoryStream>.Factory.StartNew(() => null);

            factory.EndConnect(task);

            ender.Verify(e => e.EndTask(It.Is<IAsyncResult>(r => r == task),
                                        It.IsAny<Func<AggregateException, Exception>>()));
        }
    }
}